home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Sample Code / Snippets / QuickDraw / QuickDraw™ FX / FX.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-10  |  14.0 KB  |  595 lines  |  [TEXT/KAHL]

  1. /****************************************************************************/
  2. /*                                                                            */
  3. /*    Application:    QuickDraw™ FX                                            */
  4. /*                                                                            */
  5. /*    Description:                                                            */
  6. /*                                                                            */
  7. /*    File:            FX.c                                                    */
  8. /*                                                                            */
  9. /*    Files:            FX.π                                                    */
  10. /*                    FX.π.rsrc                                                */
  11. /*                    FX.h                                                    */
  12. /*                    events.c                                                */
  13. /*                    main.c                                                    */
  14. /*                    menu.c                                                    */
  15. /*                                                                            */
  16. /*    Programmer:        Edgar Lee                                                */
  17. /*    Organization:    Apple Computer, Inc. ©1992                                */
  18. /*    Department:        Developer Technical Support, DTS                        */
  19. /*    Language:        C (Think C version 5.0.2)                                */
  20. /*    Date Created:    5-26-92                                                    */
  21. /*                                                                            */
  22. /****************************************************************************/
  23.  
  24. #include "FX.h"
  25.  
  26. void transferExample();
  27. void arithmeticExample();
  28. void colorizationExample();
  29. void ditherExample();
  30. void mappingExample();
  31. void paintBucketExample();
  32. void lassoToolExample();
  33. void pixelAverageExample();
  34. void customExample();
  35.  
  36. GrafPtr    CreateGrafPort();
  37. void    DisposeGrafPort();
  38.  
  39. pascal Boolean searchProc();
  40.  
  41. long drawFXImage()
  42. {
  43.     int        exampleNumber, exampleItem;
  44.     Rect    rect, rect2;
  45.     Rect    outlineRect;
  46.     long    startTicks, endTicks;
  47.     Point    point = { 0, 0 };
  48.     Rect    frame;
  49.     
  50.     SetRect( &rect, (*gWindow).portRect.right - (*gGWorld).portRect.right - 20, 37,
  51.                 (*gWindow).portRect.right - 20, 37 + (*gGWorld).portRect.bottom );
  52.     
  53.     outlineRect = rect;
  54.     InsetRect( &outlineRect, -5, -5 );
  55.     drawDeepBox( &outlineRect );
  56.     
  57.     frame = rect;
  58.     
  59.     if (settings.bItem == 1)
  60.     {
  61.         ForeColor( whiteColor );
  62.         PaintRect( &rect );
  63.     }
  64.     else if (settings.bItem == 2)
  65.     {
  66.         ForeColor( blackColor );
  67.         PaintRect( &rect );
  68.     }
  69.     else
  70.     {
  71.         rect2 = rect;
  72.         
  73.         rect2.right = (rect2.right - rect2.left) / 2 + rect2.left;
  74.         ForeColor( whiteColor );
  75.         PaintRect( &rect2 );
  76.         
  77.         rect2.left = rect2.right;
  78.         rect2.right = rect.right;
  79.         ForeColor( blackColor );
  80.         PaintRect( &rect2 );
  81.     }
  82.  
  83.     ForeColor( blackColor );
  84.     BackColor( whiteColor );
  85.     
  86.     exampleNumber = gCurrentExample / 10;
  87.     exampleItem = gCurrentExample % 10;
  88.     
  89.     startTicks = TickCount();
  90.     
  91.     if (exampleNumber == 1)
  92.         transferExample( &rect, exampleItem );
  93.     else if (exampleNumber == 2)
  94.         arithmeticExample( &rect, exampleItem );
  95.     else if (exampleNumber == 3)
  96.         ditherExample( &rect, exampleItem );
  97.     else if (exampleNumber == 4)
  98.         colorizationExample( &rect, exampleItem );
  99.     else if (exampleNumber == 5)
  100.         mappingExample( &rect, exampleItem );
  101.     else if (exampleNumber == 6)
  102.         paintBucketExample( &rect, exampleItem, point );
  103.     else if (exampleNumber == 7)
  104.         lassoToolExample( &rect, exampleItem, &frame );
  105.     else if (exampleNumber == 8)
  106.         pixelAverageExample( &rect, exampleItem );
  107.     else if (exampleNumber == 9)
  108.         customExample( &rect, exampleItem );
  109.         
  110.     endTicks = TickCount();
  111.     
  112.     return (endTicks - startTicks);
  113. }
  114.  
  115. void transferExample( rect, item )
  116. Rect    *rect;
  117. int        item;
  118. {
  119.     int        transferMode;
  120.     
  121.     resetItems();
  122.     settings.tItem = item;
  123.     
  124.     transferMode = setTransferMode( item );
  125.     
  126.     CopyBits( (BitMap *)(*(*gGWorld).portPixMap), &gWindow->portBits,
  127.                 &(**(*gGWorld).portPixMap).bounds, rect, transferMode, nil );
  128. }
  129.  
  130. int setTransferMode( item )
  131. int        item;
  132. {
  133.     item--;
  134.     return item;
  135. }
  136.  
  137. void arithmeticExample( rect, item )
  138. Rect    *rect;
  139. int        item;
  140. {
  141.     int            arithmeticMode;
  142.     RGBColor    color;
  143.     
  144.     resetItems();
  145.     settings.aItem = item;
  146.     
  147.     arithmeticMode = setArithmeticMode( item );
  148.     
  149.     CopyBits( (BitMap *)(*(*gGWorld).portPixMap), &gWindow->portBits,
  150.                 &(**(*gGWorld).portPixMap).bounds, rect, arithmeticMode, nil );
  151.                 
  152.     color.red = color.green = color.blue = 0;
  153.     OpColor( &color );
  154. }
  155.  
  156. int setArithmeticMode( item )
  157. int        item;
  158. {
  159.     RGBColor    color;
  160.     
  161.     if (item <= 4)
  162.         item = 31 + item;
  163.     else if (item == 9)
  164.         item = transparent;
  165.     else
  166.         item = 32 + item;
  167.     
  168.     color.red = color.green = color.blue = 0xffff / 2;
  169.     OpColor( &color );
  170.     
  171.     return item;
  172. }
  173.  
  174. void colorizationExample( rect, item )
  175. Rect    *rect;
  176. int        item;
  177. {
  178.     int            i;
  179.     Rect        srcRect, dstRect;
  180.     RGBColor    color;
  181.     
  182.     resetItems();
  183.     settings.cItem = item;
  184.     
  185.     srcRect = (**(*gGWorld).portPixMap).bounds;
  186.     srcRect.right = srcRect.left + (srcRect.right - srcRect.left) / 3;
  187.     
  188.     dstRect = *rect;
  189.     dstRect.right = dstRect.left + (dstRect.right - dstRect.left) / 3;
  190.     
  191.     for (i = 0; i < 3; i++)
  192.     {
  193.         if (item == 1)
  194.         {
  195.             ForeColor( blackColor );
  196.             BackColor( whiteColor );
  197.         }    
  198.         else if (item == 2)
  199.         {
  200.             ForeColor( whiteColor );
  201.             BackColor( blackColor );
  202.         }
  203.         else
  204.         {
  205.             color.red = color.green = color.blue = 0;
  206.         
  207.             if (i == 0)
  208.                 color.red = 0xffff;
  209.             else if (i == 1)
  210.                 color.green = 0xffff;
  211.             else if (i == 2)
  212.                 color.blue = 0xffff;
  213.             
  214.             if (item == 3)
  215.             {
  216.                 RGBForeColor( &color );
  217.                 BackColor( whiteColor );
  218.             }
  219.             else
  220.             {
  221.                 RGBBackColor( &color );
  222.                 ForeColor( blackColor );
  223.             }
  224.         }
  225.                 
  226.         CopyBits( (BitMap *)(*(*gGWorld).portPixMap), &gWindow->portBits,
  227.                 &srcRect, &dstRect, srcCopy, nil );
  228.                 
  229.         OffsetRect( &srcRect, srcRect.right - srcRect.left, 0 );
  230.         OffsetRect( &dstRect, dstRect.right - dstRect.left, 0 );
  231.     }
  232. }
  233.  
  234. void ditherExample( rect, item )
  235. Rect    *rect;
  236. int        item;
  237. {
  238.     int        ditherMode;
  239.     
  240.     /* This function shows an example of using copybits with the dithering. */
  241.     
  242.     resetItems();
  243.     settings.dItem = item;
  244.     
  245.     ditherMode = setDitherMode( item );
  246.     
  247.     CopyBits( (BitMap *)(*(*gGWorld).portPixMap), &gWindow->portBits,
  248.                 &(**(*gGWorld).portPixMap).bounds, rect, srcCopy + ditherMode, nil );
  249. }
  250.  
  251. int setDitherMode( item )
  252. int        item;
  253. {
  254.     if (item == 1)
  255.         return 0;
  256.     else
  257.         return ditherCopy;
  258. }
  259.  
  260. void mappingExample( rect, item )
  261. Rect    *rect;
  262. int        item;
  263. {
  264.     int            i;
  265.     CTabHandle    ctable;
  266.     GWorldPtr    gworld;
  267.     CTabHandle    ictable;
  268.     
  269.     resetItems();
  270.     settings.mItem = item;
  271.     
  272.     if (item == 1)
  273.         CopyBits( (BitMap *)(*(*gGWorld).portPixMap), &gWindow->portBits,
  274.             &(**(*gGWorld).portPixMap).bounds, rect, srcCopy, nil );
  275.     else if (item == 2)
  276.     {
  277.         AddSearch( searchProc );
  278.         
  279.         CopyBits( (BitMap *)(*(*gGWorld).portPixMap), &gWindow->portBits,
  280.             &(**(*gGWorld).portPixMap).bounds, rect, srcCopy, nil );
  281.         
  282.         DelSearch( searchProc );
  283.     }
  284.     else if (item == 3)
  285.     {
  286.         NewGWorld( &gworld, 8, &(*gGWorld).portRect, GetCTable( 8 + 64 ), nil, 0 );
  287.         
  288.         CopyBits( (BitMap *)(*(*gGWorld).portPixMap), (BitMap *)(*(*gworld).portPixMap),
  289.                     &(**(*gGWorld).portPixMap).bounds, &(**(*gworld).portPixMap).bounds,
  290.                     srcCopy, nil );
  291.         
  292.         ictable = GetCTable( 8 );
  293.         
  294.         for (i = 0; i <= (**(**(*gworld).portPixMap).pmTable).ctSize; i++)
  295.             (**(**(*gworld).portPixMap).pmTable).ctTable[i].rgb =
  296.                     (**ictable).ctTable[255 - i].rgb;
  297.         
  298.         (**(**(*gworld).portPixMap).pmTable).ctSeed = 67;
  299.     //            (**(**(*(CGrafPtr)gWindow).portPixMap).pmTable).ctSeed; 
  300.         
  301.         CopyBits( (BitMap *)(*(*gworld).portPixMap), &gWindow->portBits,
  302.             &(**(*gworld).portPixMap).bounds, rect, srcCopy, nil );
  303.         
  304.         DisposeGWorld( gworld );
  305.     }
  306. }
  307.  
  308. pascal Boolean searchProc( color, position )
  309. RGBColor    *color;
  310. long        *position;
  311. {
  312.     (*color).red = 0;
  313.     
  314.     return false;
  315. }
  316.  
  317. void paintBucketExample( rect, exampleItem, point )
  318. Rect    *rect;
  319. int        exampleItem;
  320. Point    point;
  321. {
  322.     GrafPtr     mask;
  323.     CGrafPtr    currentPort;
  324.     GDHandle    currentDevice;
  325.     Point        newPoint;
  326.     GWorldPtr    gworld;
  327.     
  328.     resetItems();
  329.  
  330.     newPoint.h = point.h - 20;
  331.     newPoint.v = point.v - 37;
  332.  
  333.     if (newPoint.h < 0 || newPoint.v < 0 ||
  334.         newPoint.h > ((**(*gGWorld).portPixMap).bounds.right - (**(*gGWorld).portPixMap).bounds.left) ||
  335.         newPoint.v > ((**(*gGWorld).portPixMap).bounds.bottom - (**(*gGWorld).portPixMap).bounds.top))
  336.         return;
  337.         
  338.     mask = CreateGrafPort( &(*gGWorld).portRect );
  339.     
  340.     ForeColor( redColor );
  341.     MoveTo( point.h - 2, point.v );
  342.     LineTo( point.h + 2, point.v );
  343.     MoveTo( point.h, point.v - 2 );
  344.     LineTo( point.h, point.v + 2 );
  345.  
  346.     ForeColor( blackColor );
  347.  
  348.     NewGWorld( &gworld, 8, &(*gGWorld).portRect, GetCTable( 8 + 64 ), nil, 0 );
  349.         
  350.     CopyBits( (BitMap *)(*(*gGWorld).portPixMap), (BitMap *)(*(*gworld).portPixMap),
  351.                     &(**(*gGWorld).portPixMap).bounds, &(**(*gworld).portPixMap).bounds,
  352.                     srcCopy, nil );
  353.                     
  354. //    GetGWorld( ¤tPort, ¤tDevice );
  355. //    SetGWorld( gworld, nil );
  356.     
  357.     SeedCFill( (BitMap *)(*(*gworld).portPixMap), &mask->portBits,
  358.                 &(**(*gworld).portPixMap).bounds, &mask->portRect,
  359.                 newPoint.h, newPoint.v, nil, 0 );
  360. //    SetGWorld( currentPort, currentDevice );
  361.     
  362.     CopyMask( (BitMap *)(*(*gworld).portPixMap), &mask->portBits, &gWindow->portBits,
  363.                 &(**(*gworld).portPixMap).bounds, &mask->portRect, rect );
  364.     
  365.     DisposeGrafPort( mask );
  366. }
  367.  
  368. void lassoToolExample( rect, exampleItem, frame )
  369. Rect    *rect;
  370. int        exampleItem;
  371. Rect    *frame;
  372. {
  373.     Rect        bounds;
  374.     GrafPtr     mask;
  375.     RGBColor    color;
  376.     CGrafPtr    currentPort;
  377.     GDHandle    currentDevice;
  378.     
  379.     pascal Boolean matchProc();
  380.     
  381.     resetItems();
  382.  
  383.     mask = CreateGrafPort( &(*gGWorld).portRect );
  384.  
  385.     GetGWorld( ¤tPort, ¤tDevice );
  386.     SetGWorld( gGWorld, nil );
  387.     
  388.     color.red = color.green = color.blue = 0;
  389.     
  390.     CalcCMask( (BitMap *)(*(*gGWorld).portPixMap), &mask->portBits,
  391.                 &(**(*gGWorld).portPixMap).bounds, &mask->portRect,
  392.                 &color, matchProc, 0 );
  393.     SetGWorld( currentPort, currentDevice );
  394.     
  395.     CopyMask( (BitMap *)(*(*gGWorld).portPixMap), &mask->portBits, &gWindow->portBits,
  396.                 &(**(*gGWorld).portPixMap).bounds, &mask->portRect, rect );
  397. /*
  398.     bounds = *frame;
  399.     OffsetRect( &bounds, -bounds.left, -bounds.top );
  400.     
  401.     mask = CreateGrafPort( &bounds );
  402.  
  403.     GetGWorld( ¤tPort, ¤tDevice );
  404.     SetGWorld( gGWorld, nil );
  405.     
  406.     color.red = color.green = color.blue = 0;
  407.     
  408.     CalcCMask( (BitMap *)(*(*gGWorld).portPixMap), &mask->portBits,
  409.                 &bounds, &mask->portRect, &color, matchProc, 0 );
  410.                 
  411.     SetGWorld( currentPort, currentDevice );
  412.         
  413.     CopyMask( (BitMap *)(*(*gGWorld).portPixMap), &mask->portBits, &gWindow->portBits,
  414.                 &bounds, &mask->portRect, frame );
  415. */
  416.     
  417.     DisposeGrafPort( mask );
  418. }
  419.  
  420. pascal Boolean matchProc( color, position )
  421. RGBColor    *color;
  422. long        *position;
  423. {    
  424.     GDHandle    currDevice;
  425.     MatchRec    *matchInfo;
  426.     
  427.     currDevice = GetGDevice();
  428.     matchInfo = (MatchRec *)(**currDevice).gdRefCon;
  429.  
  430.     if (matchInfo->red == color->red && matchInfo->green == color->green &&
  431.         matchInfo->blue == color->blue)
  432.         *position = 0;
  433.     else
  434.         *position = 1;
  435.         
  436.     return true;
  437. }
  438.  
  439. void pixelAverageExample( rect, item )
  440. Rect    *rect;
  441. int        item;
  442. {
  443.     Rect        bounds;
  444.     GWorldPtr    gworld;
  445.     GWorldPtr    source;
  446.     
  447.     resetItems();
  448.     
  449.     /* Create 8-bit gworld from 32-bit original. */
  450.     
  451.     NewGWorld( &source, 8, &(*gGWorld).portRect, GetCTable( 8 + 64 ), nil, 0 );
  452.     CopyBits( (BitMap *)(*(*gGWorld).portPixMap), (BitMap *)(*(*source).portPixMap),
  453.             &(**(*gGWorld).portPixMap).bounds, &(**(*source).portPixMap).bounds,
  454.             srcCopy, nil );
  455.     
  456.     /* Create another 8-bit gworld at quarter size of original. */
  457.         
  458.     SetRect( &bounds, 0, 0, (*gGWorld).portRect.right / 4,
  459.                 (*gGWorld).portRect.bottom / 4 );
  460.     
  461.     NewGWorld( &gworld, 8, &bounds, GetCTable( 8 + 64 ), nil, 0 );
  462.  
  463.     /* Copy the 8-bit original to 8-bit quarter image without pixel averaging. */
  464.     
  465.     bounds = (*source).portRect;
  466.     
  467.     CopyBits( (BitMap *)(*(*source).portPixMap), (BitMap *)(*(*gworld).portPixMap),
  468.             &(**(*source).portPixMap).bounds, &(**(*gworld).portPixMap).bounds,
  469.             srcCopy, nil );
  470.     
  471.     /* Copy the quarter image to screen. */
  472.     
  473.     OffsetRect( &bounds, 20, 37 );
  474.     CopyBits( (BitMap *)(*(*gworld).portPixMap), &(*gWindow).portBits,
  475.             &(**(*gworld).portPixMap).bounds, &bounds, srcCopy, nil );
  476.     
  477.     /* Now, copy the 8-bit original to 8-bit quarter image with pixel averaging. */
  478.     
  479.     bounds = (*source).portRect;
  480.     
  481.     CopyBits( (BitMap *)(*(*source).portPixMap), (BitMap *)(*(*gworld).portPixMap),
  482.             &(**(*source).portPixMap).bounds, &(**(*gworld).portPixMap).bounds,
  483.             srcCopy + ditherCopy, nil );
  484.     
  485.     /* Finally, copy pixel averaged quarter image to screen. */
  486.             
  487.     OffsetRect( &bounds, (*rect).left, (*rect).top );
  488.     CopyBits( (BitMap *)(*(*gworld).portPixMap), &(*gWindow).portBits,
  489.             &(**(*gworld).portPixMap).bounds, &bounds, srcCopy, nil );
  490.     
  491.     DisposeGWorld( source );
  492.     DisposeGWorld( gworld );
  493. }
  494.  
  495. void customExample( rect, item )
  496. Rect    *rect;
  497. int        item;
  498. {
  499.     int            transferMode;
  500.     int            ditherMode;
  501.     RGBColor    color;
  502.         
  503.     transferMode = setTransferMode( settings.tItem );
  504.     ditherMode = setDitherMode( settings.dItem );
  505.     
  506.     if (settings.cItem == 1)
  507.     {
  508.         ForeColor( blackColor );
  509.         BackColor( whiteColor );
  510.     }
  511.     else if (settings.cItem == 2)
  512.     {
  513.         ForeColor( whiteColor );
  514.         BackColor( blackColor );
  515.     }
  516.     else if (settings.cItem == 3)
  517.     {
  518.         color.green = 0xffff;
  519.         color.red = color.blue = 0;
  520.         RGBForeColor( &color );
  521.         BackColor( whiteColor );
  522.     }
  523.     else if (settings.cItem == 4)
  524.     {
  525.         color.green = 0xffff;
  526.         color.red = color.blue = 0;
  527.         ForeColor( blackColor );
  528.         RGBBackColor( &color );
  529.     }
  530.  
  531.     if (settings.mItem == 2)
  532.         AddSearch( searchProc );
  533.     
  534.     CopyBits( (BitMap *)(*(*gGWorld).portPixMap), &gWindow->portBits,
  535.                 &(**(*gGWorld).portPixMap).bounds, rect,
  536.                 transferMode + ditherMode, nil );
  537.                 
  538.     if (settings.mItem == 2)
  539.         DelSearch( searchProc );
  540. }
  541.  
  542. GrafPtr CreateGrafPort( bounds )    /* Originally written by Forrest Tanaka. */
  543. Rect *bounds;
  544. {
  545.     GrafPtr    savedPort;        /* Saved GrafPtr for later restore. */
  546.     GrafPtr    newPort;        /* New GrafPort. */
  547.     Rect    localBounds;    /* Local copy of bounds. */
  548.  
  549.     GetPort( &savedPort );
  550.  
  551.     /* Set the top-left corner of bounds to (0,0). */
  552.     localBounds = *bounds;
  553.     OffsetRect( &localBounds, -bounds->left, -bounds->top );
  554.  
  555.     /* Allocate a new GrafPort. */
  556.     newPort = (GrafPtr)NewPtrClear( sizeof( GrafPort ) );
  557.     
  558.     if (newPort != nil)
  559.     {
  560.         /* Initialize the new port and make the current port. */
  561.         OpenPort( newPort );
  562.  
  563.         /* Initialize and allocate the bitmap. */
  564.         newPort->portBits.bounds = localBounds;
  565.           newPort->portBits.rowBytes = ((localBounds.right + 15) >> 4) << 1;
  566.         newPort->portBits.baseAddr =  NewPtrClear( newPort->portBits.rowBytes *
  567.                                                     (long)localBounds.bottom );
  568.         if (newPort->portBits.baseAddr != nil)
  569.         {
  570.             /* Clean up the new port. */
  571.             newPort->portRect = localBounds;
  572.             ClipRect( &localBounds );
  573.             RectRgn( newPort->visRgn, &localBounds );
  574.             EraseRect( &localBounds );
  575.         }
  576.         else
  577.         {
  578.             /* Allocation failed; deallocate the port. */
  579.             ClosePort( newPort );
  580.             DisposPtr( (Ptr)newPort );
  581.             newPort = nil;
  582.         }
  583.     }
  584.     
  585.     SetPort( savedPort );
  586.     return newPort;
  587. }
  588.  
  589. void DisposeGrafPort( doomedPort )        /* Originally written by Forrest Tanaka. */
  590. GrafPtr doomedPort;
  591. {
  592.     ClosePort( doomedPort );
  593.     DisposPtr( doomedPort->portBits.baseAddr );
  594.     DisposPtr( (Ptr)doomedPort );
  595. }